﻿using System;
using System.Collections.Generic;
using RpcHelper.Error;

namespace RpcHelper
{
    /// <summary>
    /// 错误异常
    /// </summary>
    public class ErrorException : Exception
    {
        /// <summary>
        /// 异常信息
        /// </summary>
        /// <param name="message">消息</param>
        public ErrorException(string code, LogGrade grade = LogGrade.Information)
        {
            this.ErrorCode = LocalErrorManage.Format(code, out this._Param);
            this.LogGrade = grade;
        }
        public ErrorException(string code, Dictionary<string, string> args)
        {
            this.ErrorCode = LocalErrorManage.Format(code, out this._Param);
            this.LogGrade = LogGrade.Information;
            this.Args = args;
        }
        public ErrorException(string code, string remark, Dictionary<string, string> args)
        {
            this.Remark = remark;
            this.LogGrade = LogGrade.Information;
            this.ErrorCode = LocalErrorManage.Format(code, out this._Param);
            this.Args = args;
        }
        public ErrorException(Exception e, Dictionary<string, string> args) : base(e.Message, e)
        {
            this.Args = args;
            if (e is ErrorException i)
            {
                this.IsSystemError = i.IsSystemError;
                this.ErrorCode = i.ErrorCode;
                this.LogGrade = i.LogGrade;
                if (i.Args != null)
                {
                    this._InitArgs(i.Args);
                }
            }
            else
            {
                this.LogGrade = LogGrade.ERROR;
                this.ErrorCode = "public.system.error";
                this.IsSystemError = true;
            }
        }
        public ErrorException(Exception e, string code, Dictionary<string, string> args) : base(e.Message, e)
        {
            this.Args = args;
            if (e is ErrorException i)
            {
                this.IsSystemError = i.IsSystemError;
                this.ErrorCode = i.ErrorCode;
                this.LogGrade = i.LogGrade;
                if (i.Args != null)
                {
                    this._InitArgs(i.Args);
                }
            }
            else
            {
                this.LogGrade = LogGrade.ERROR;
                this.ErrorCode = code;
                this.IsSystemError = true;
            }
        }


        public ErrorException(Exception e, LogGrade grade = LogGrade.ERROR) : base(e.Message, e)
        {
            this.LogGrade = grade;
            if (e is ErrorException i)
            {
                this.IsSystemError = i.IsSystemError;
                this.ErrorCode = i.ErrorCode;
                if (i.Args != null)
                {
                    this._InitArgs(i.Args);
                }
            }
            else
            {
                this.ErrorCode = "public.system.error";
                this.IsSystemError = true;
            }
        }
        /// <summary>
        /// 异常信息
        /// </summary>
        /// <param name="code"></param>
        /// <param name="param"></param>
        public ErrorException(string code, string param, LogGrade grade = LogGrade.Information) : this(code, grade)
        {
            this._Param = param;
        }
        public string Remark
        {
            get;
            set;
        }
        private void _InitArgs(Dictionary<string, string> args)
        {
            if (this.Args == null)
            {
                this.Args = args;
                return;
            }
            foreach (KeyValuePair<string, string> i in args)
            {
                this.Args.Add(i.Key, i.Value);
            }

        }
        public Dictionary<string, string> Args
        {
            get;
            set;
        }
        private readonly string _Param = null;

        private string _Msg = null;

        public bool IsSystemError
        {
            get;
            private set;
        }
        /// <summary>
        /// 错误信息
        /// </summary>
        public override string Message
        {
            get
            {
                if (this._Msg == null)
                {
                    this._Msg = LocalErrorManage.GetText(this.ErrorCode, this.ErrorCode);
                }
                return this._Msg;
            }
        }
        /// <summary>
        /// 是否结束
        /// </summary>
        public bool IsEnd
        {
            get;
            set;
        }
        /// <summary>
        /// 错误码
        /// </summary>
        public string ErrorCode
        {
            get;
        }
        /// <summary>
        /// 日志级别
        /// </summary>
        public LogGrade LogGrade { get; } = LogGrade.ERROR;
        /// <summary>
        /// 参数值
        /// </summary>
        public string Param => this._Param;
        public ErrorMsg GetError()
        {
            ErrorMsg msg = LocalErrorManage.Get(this.ErrorCode);
            if (msg == null)
            {
                return new ErrorMsg
                {
                    ErrorId = -1,
                    ErrorCode = this.ErrorCode,
                    Text = this.ErrorCode,
                    Lang = LocalErrorManage.DefLang
                };
            }
            return msg;
        }

        public override string ToString()
        {
            if (this._Param == null)
            {
                return this.ErrorCode;
            }
            return string.Format("{0}[{1}]", this.ErrorCode, this._Param);
        }
        public static ErrorException FormatError(Exception e)
        {
            if (e.InnerException != null)
            {
                e = e.InnerException;
            }
            if (e is ErrorException k)
            {
                return k;
            }
            return new ErrorException(e);
        }
        public static ErrorException FormatError(Exception e, LogGrade grade)
        {
            if (e.InnerException != null)
            {
                e = e.InnerException;
            }
            if (e is ErrorException k)
            {
                return k;
            }
            return new ErrorException(e, grade);
        }
        public void SaveLog(string group = "def")
        {
            if (LogSystem.CheckIsRecord(this.LogGrade))
            {
                new ErrorLog(this, group).Save();
            }
        }

        public void SaveLog(string show, string group = "def")
        {
            if (LogSystem.CheckIsRecord(this.LogGrade))
            {
                return;
            }
            new ErrorLog(this, group)
            {
                LogContent = show
            }.Save();
        }
    }
}
